#define scucp static const unsigned char PROGMEM
#include <SPI.h>
#include <Wire.h>
#include <DHT.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <avr/pgmspace.h>
#include <WiFiUdp.h>
#include <NTPClient.h>
#include <DNSServer.h>
#include <ArduinoJson.h>


// Default Wifi config
const char* i_ssid     = "auto_kx_c2-411";
const char* i_password = "c2411c2411";
char Hostname[10] = "espsc";

// Web wifi config
const char* AP_NAME = "ESP8266智能闹钟";
char sta_ssid[32] = {0};
char sta_password[64] = {0};
bool webconfigFlag = false;
// web html code
const char* wifi_html = "\
<!DOCTYPE html>\r\n\
<html lang='en'>\r\n\
<head>\r\n\
  <meta charset='UTF-8'>\r\n\
  <meta name='viewport' content='width=device-width, initial-scale=1.5'>\r\n\
  <title>Document</title>\r\n\
</head>\r\n\
<body>\r\n\
  <form name='input' action='/' method='POST'>\r\n\
        wifi名称: <br>\r\n\
        <input type='text' name='ssid'><br>\r\n\
        wifi密码:<br>\r\n\
        <input type='text' name='password'><br>\r\n\
        <input type='submit' value='保存(点击一次！)'>\r\n\
    </form>\r\n\
</body>\r\n\
</html>\r\n\
";

const char* alarm_html = "\
<!DOCTYPE html>\r\n\
<html lang='en'>\r\n\
<head>\r\n\
  <meta charset='UTF-8'>\r\n\
  <meta name='viewport' content='width=device-width, initial-scale=1.5'>\r\n\
  <title>Document</title>\r\n\
</head>\r\n\
<body>\r\n\
  <form name='input' action='/' method='POST'>\r\n\
        是否开启闹钟(0关闭1开启):<br>\r\n\
        <input type='text' name='asetAlarm'><br>\r\n\
        时(24小时制, 00-23的两位整数): <br>\r\n\
        <input type='text' name='aHour'><br>\r\n\
        分(00-59的两位整数):<br>\r\n\
        <input type='text' name='aMinute'><br>\r\n\
        <p>点击一次，若无反应20s后重试</p><br>\r\n\
        <input type='submit' value='保存'>\r\n\
    </form>\r\n\
</body>\r\n\
</html>\r\n\
";

// IP, DNS, WebServer Initialize
const byte DNS_PORT = 53;
IPAddress apIP(192, 168, 4, 1);
DNSServer dnsServer;
ESP8266WebServer webServer(80);

// NTP config
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "ntp.aliyun.com", 60*60*8, 30*60*1000);

// Weather config
const char* host = "api.seniverse.com"; //weather api host
const int httpPort = 80; //host port
String reqUserKey = "********"; //Todo: Api key, remenber to hide before turn in
String reqLocation = "chengdu"; //city
String reqUnit = "c"; 
// HTTP GET message
String reqRes = "/v3/weather/daily.json?key=" + reqUserKey +
                  + "&location=" + reqLocation + 
                  "&language=en&unit=" +reqUnit + "&start=0&days=3";
String todayDate = "";
bool dateFlag = true;
bool weatherFlag = true;


// OLED config and initial
#define SCREEN_WIDTH 128  // OLED Display Width in pixel
#define SCREEN_HEIGHT 64  // OLED Display height in pixel
#define OLED_MOSI   12    //D6
#define OLED_CLK   13     //D7
#define OLED_DC    14     //D5
#define OLED_CS    15     //D8
#define OLED_RESET 16     //D0 
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT,OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);

// DHT11 and buzzer config
#define DHTTYPE DHT11
#define DHT11_PIN 4
#define BUZZER_PIN 5
DHT dht(DHT11_PIN, DHTTYPE);

// word stock
scucp znnz[][32] = 
{
{0x20,0x00,0x3E,0x7C,0x48,0x44,0x08,0x44,0xFF,0x44,0x14,0x44,0x22,0x7C,0x40,0x00,0x1F,0xF0,0x10,0x10,0x10,0x10,0x1F,0xF0,0x10,0x10,0x10,0x10,0x1F,0xF0,0x10,0x10},
{0x10,0x40,0x24,0x44,0x42,0x48,0xFF,0x70,0x01,0x40,0x00,0x42,0x7E,0x42,0x42,0x3E,0x42,0x00,0x7E,0x44,0x42,0x48,0x42,0x70,0x7E,0x40,0x42,0x42,0x4A,0x42,0x44,0x3E},
{0x20,0x00,0x17,0xFC,0x00,0x04,0x42,0x04,0x41,0x04,0x5F,0xF4,0x41,0x04,0x41,0x04,0x4F,0xE4,0x49,0x24,0x49,0x24,0x49,0xA4,0x49,0x44,0x41,0x04,0x41,0x14,0x40,0x08},
{0x10,0x20,0x10,0x20,0x3C,0x20,0x20,0x20,0x41,0xFC,0xBD,0x24,0x11,0x24,0x11,0x24,0xFD,0x24,0x11,0xFC,0x11,0x24,0x10,0x20,0x14,0x20,0x18,0x20,0x10,0x20,0x00,0x20}
};

scucp wenshi[][32] = 
{
{0x00,0x00,0x23,0xF8,0x12,0x08,0x12,0x08,0x83,0xF8,0x42,0x08,0x42,0x08,0x13,0xF8,0x10,0x00,0x27,0xFC,0xE4,0xA4,0x24,0xA4,0x24,0xA4,0x24,0xA4,0x2F,0xFE,0x00,0x00},
{0x00,0x00,0x27,0xF8,0x14,0x08,0x14,0x08,0x87,0xF8,0x44,0x08,0x44,0x08,0x17,0xF8,0x11,0x20,0x21,0x20,0xE9,0x24,0x25,0x28,0x23,0x30,0x21,0x20,0x2F,0xFE,0x00,0x00}
};

scucp alarm_icon[32] = {0x00,0x00,0x10,0x08,0x20,0x04,0x43,0xC2,0x05,0x20,0x09,0x10,0x11,0x08,0x11,0xF8,0x10,0x08,0x08,0x10,0x0C,0x30,0x1F,0xF8,0x18,0x18,0x30,0x0C,0x20,0x04,0x00,0x00};

scucp jinming[][32] = 
{
{0x01,0x00,0x01,0x00,0x02,0x80,0x04,0x40,0x08,0x20,0x12,0x10,0x21,0x08,0xC1,0x06,0x00,0x00,0x1F,0xF0,0x00,0x10,0x00,0x20,0x00,0x20,0x00,0x40,0x00,0x80,0x01,0x00},
{0x00,0x00,0x00,0xFC,0x7C,0x84,0x44,0x84,0x44,0x84,0x44,0xFC,0x7C,0x84,0x44,0x84,0x44,0x84,0x44,0xFC,0x7C,0x84,0x44,0x84,0x01,0x04,0x01,0x04,0x02,0x14,0x04,0x08},
{0x00,0x00,0x3F,0xF8,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0xFF,0xFE,0x01,0x00,0x02,0x80,0x02,0x80,0x04,0x40,0x04,0x40,0x08,0x20,0x10,0x10,0x20,0x08,0xC0,0x06}
};

scucp tianqi[][32] =
{
//0晴, 1阴, 2多, 3云, 4小, 5中, 6大, 7暴, 8阵, 9雨
{0x00,0x20,0x00,0x20,0x7B,0xFE,0x48,0x20,0x49,0xFC,0x48,0x20,0x4B,0xFE,0x78,0x00,0x49,0xFC,0x49,0x04,0x49,0xFC,0x49,0x04,0x79,0xFC,0x49,0x04,0x01,0x14,0x01,0x08},//"晴",
{0x00,0x00,0x7D,0xFC,0x45,0x04,0x49,0x04,0x49,0x04,0x51,0xFC,0x49,0x04,0x49,0x04,0x45,0x04,0x45,0xFC,0x45,0x04,0x69,0x04,0x52,0x04,0x42,0x04,0x44,0x14,0x48,0x08},//"阴",
{0x02,0x00,0x02,0x00,0x07,0xF0,0x08,0x20,0x38,0x40,0x04,0x80,0x03,0x40,0x0C,0x80,0x71,0xF8,0x02,0x08,0x0C,0x10,0x32,0x20,0x01,0x40,0x01,0x80,0x0E,0x00,0x70,0x00},//"多",
{0x00,0x00,0x3F,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFE,0x02,0x00,0x04,0x00,0x04,0x00,0x08,0x40,0x10,0x20,0x20,0x10,0x7F,0xF8,0x20,0x08,0x00,0x08},//"云",
{0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x11,0x10,0x11,0x08,0x11,0x04,0x21,0x04,0x21,0x02,0x41,0x02,0x81,0x02,0x01,0x00,0x01,0x00,0x05,0x00,0x02,0x00},//"小",
{0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x3F,0xF8,0x21,0x08,0x21,0x08,0x21,0x08,0x21,0x08,0x21,0x08,0x3F,0xF8,0x21,0x08,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00},//"中",
{0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0xFF,0xFE,0x01,0x00,0x01,0x00,0x02,0x80,0x02,0x80,0x04,0x40,0x04,0x40,0x08,0x20,0x10,0x10,0x20,0x08,0xC0,0x06},//*"大",
{0x1F,0xF0,0x10,0x10,0x1F,0xF0,0x10,0x10,0x1F,0xF0,0x08,0x20,0x7F,0xFC,0x08,0x20,0xFF,0xFE,0x08,0x20,0x31,0x18,0xC9,0x26,0x05,0x40,0x09,0x20,0x15,0x10,0x22,0x08},
{0x00,0x40,0x7C,0x40,0x44,0x40,0x4B,0xFE,0x48,0x80,0x50,0xA0,0x49,0x20,0x49,0xFC,0x44,0x20,0x44,0x20,0x44,0x20,0x6B,0xFE,0x50,0x20,0x40,0x20,0x40,0x20,0x40,0x20},
{0x00,0x00,0xFF,0xFE,0x01,0x00,0x01,0x00,0x01,0x00,0x7F,0xFC,0x41,0x04,0x41,0x04,0x49,0x44,0x45,0x24,0x41,0x04,0x49,0x44,0x45,0x24,0x41,0x04,0x41,0x14,0x40,0x08}//*"雨",
};

// Variables
int displayWeatherGap = 0;

typedef struct
{
  String date;
  String high;
  String low;
  int code_day;
  String humidity;
  String wind_scale;
}weatherInfo;

typedef struct
{
  String humidity;
  String temperature;
}dhtInfo;

typedef struct
{
  String setAlarm;
  String hour;
  String minute;
  bool ringed;
}alarmInfo;

weatherInfo day1, day2, day3;
dhtInfo dht11Info;
alarmInfo alarm;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  if(!display.begin(SSD1306_SWITCHCAPVCC))
{
   Serial.println(F("SSD1306 allocation failed"));
   for(;;); // Don't proceed, loop forever
  }

  pinMode(DHT11_PIN, INPUT);
  WiFi.hostname(Hostname);
  
  initSoftAP();
  initWebServer();
  initDNS();

  alarm.setAlarm = "0";
  alarm.ringed = false;

  // Try to connect Default WiFi
  // If failed, enable webconfig
  if( sta_ssid[0] == 0){
      strcpy(sta_ssid, i_ssid);
      strcpy(sta_password, i_password);
    }
  // buzzer();
  connectNewWifi();
  
    // setup date info
    if (WiFi.status() == WL_CONNECTED){
      Serial.println(".");
      Serial.println("connected");
      Serial.println(WiFi.localIP());
      httpRequest(reqRes);
    }else{
      displayDISCON(100);
      }
    
    timeClient.begin();

}

void loop() {
  // put your main code here, to run repeatedly:
  while(webconfigFlag){
    dnsServer.processNextRequest();
    webServer.handleClient();
  }
  dnsServer.processNextRequest();
  webServer.handleClient();
  if(WiFi.status() == WL_CONNECTED){
    displayTime();
    showTitle();
    displayDate();
    display.display();
    delay(1000);
    displayWeatherGap++;

    // Every 10 min to display weather
    if (displayWeatherGap > 10){
      httpRequest(reqRes);
      dht11();
      displayWeatherGap = 0;
      display.clearDisplay();
      display.setTextSize(2);
      display.setTextColor(WHITE);
      display.setCursor(15, 24);
      display.printf("Loading");
      display.display();
      delay(300);
      displayWeather(day1);
      displayWeather(day2);
      alarm.ringed = (alarm.ringed == true)?false:false;
    }
  }else {
    // If wifi discon, retry
    displayDISCON(500);
    connectNewWifi();
  }
}

void showTitle(){
  display.drawBitmap(32,0,znnz[0],16,16,1);
  display.drawBitmap(48,0,znnz[1],16,16,1);
  display.drawBitmap(64,0,znnz[2],16,16,1);
  display.drawBitmap(80,0,znnz[3],16,16,1);
  
}

void displayTime(){
  timeClient.update();
  display.clearDisplay();
  display.setTextSize(2);
  display.setTextColor(WHITE);
  // a little bit margin
  display.setCursor(34,24);
  // cut off the sec
  char Time[6] = "";
  strncpy(Time,timeClient.getFormattedTime().c_str(),5);
  // Serial.println(Time);
  display.printf(Time);
  if (alarm.setAlarm == "1"){
      display.drawBitmap(112,0,alarm_icon,16,16,1);
        checkAlarm(Time);
    }
}

void httpRequest(String reqRes){
  WiFiClient client;
 
  // HTTP GET request header
  String httpRequest = String("GET ") + reqRes + " HTTP/1.1\r\n" + 
                              "Host: " + host + "\r\n" + 
                              "Connection: close\r\n\r\n";
  Serial.println(""); 
  Serial.print("Connecting to "); Serial.print(host);
 
  if (client.connect(host, 80)){
    Serial.println(" Success!");
 
    // Sending request
    client.print(httpRequest);
    Serial.println("Sending request..."); 
 
    // Print status code
    String status_response = client.readStringUntil('\n');
    Serial.print("status_response: ");
    Serial.println(status_response);
 
    // Bypass header
    if (client.find("\r\n\r\n")) {
      Serial.println("Found Header End. Start Parsing.");
    }
    // Parsing weather info from seniverse with ArduinoJson lib
    parseInfo(client);
  } else {
    Serial.println(" connection failed!");
    dateFlag = false;
    weatherFlag = false;
    
  }
  client.stop(); 
}

void parseInfo(WiFiClient client){
  // Stream& input;
  DynamicJsonDocument doc(1536);
  DeserializationError error = deserializeJson(doc, client);
  if (error) {
    Serial.print(F("deserializeJson() failed: "));
    Serial.println(error.f_str());
    return;
}
  
  JsonObject daily_0 = doc["results"][0]["daily"][0];
  JsonObject daily_1 = doc["results"][0]["daily"][1];
  JsonObject daily_2 = doc["results"][0]["daily"][2];

  const char* daily_0_date = daily_0["date"];
  const char* daily_1_date = daily_1["date"];
  const char* daily_2_date = daily_2["date"];
  
  const char* daily_0_high = daily_0["high"];
  const char* daily_1_high = daily_1["high"];
  const char* daily_2_high = daily_2["high"];
  const char* daily_0_low = daily_0["low"];
  const char* daily_1_low = daily_1["low"];
  const char* daily_2_low = daily_2["low"];
  const char* daily_0_code_day = daily_0["code_day"];
  const char* daily_1_code_day = daily_1["code_day"];
  const char* daily_2_code_day = daily_2["code_day"];
  const char* daily_0_humidity = daily_0["humidity"];
  const char* daily_1_humidity = daily_1["humidity"];
  const char* daily_2_humidity = daily_2["humidity"];
  const char* daily_0_wind_scale = daily_0["wind_scale"];
  const char* daily_1_wind_scale = daily_1["wind_scale"];
  const char* daily_2_wind_scale = daily_2["wind_scale"];
  
  todayDate = daily_0_date;
  day1.date = daily_0_date;
  day1.high = daily_0_high;
  day1.low = daily_0_low;
  day1.code_day = atoi(daily_0_code_day);

  day2.date = daily_1_date;
  day2.high = daily_1_high;
  day2.low = daily_1_low;
  day2.code_day = atoi(daily_1_code_day);

  dateFlag = true;
 
  // Serial debug
  Serial.println(F("======Weahter======="));
  Serial.print("Date: ");
  Serial.println(todayDate);
  Serial.println(day1.high);
  Serial.println(day1.low);
  
}

void displayDate(){
  display.setTextSize(2);
  display.setTextColor(WHITE);
  if(dateFlag){
    display.setCursor(4, 49);
    display.printf(day1.date.c_str());
  }else{
    display.setCursor(10, 49);
    display.printf("No Date");
    }
  }

void displayWeather(weatherInfo day){
  display.clearDisplay();
  display.setTextSize(2);
  display.setTextColor(WHITE);

  if(day.date == todayDate){
      display.drawBitmap(3,46,jinming[0],16,16,1);
      display.drawBitmap(19,46,jinming[2],16,16,1);
    }else{
      display.drawBitmap(3,46,jinming[1],16,16,1);
      display.drawBitmap(19,46,jinming[2],16,16,1);
    }

  // Display date
  char temp[11] = "";
  char* date;
  strncpy(temp, todayDate.c_str(), 10);
  date = substring(temp, 5, 5);
  display.setCursor(66, 50);
  display.printf(date);

  // Display humidity and temperature
  display.drawBitmap(60,17,wenshi[0],16,16,1);
  display.setCursor(76, 17);
  display.printf(dht11Info.temperature.c_str());

  display.drawBitmap(60,31,wenshi[1],16,16,1);
  display.setCursor(76, 31);
  display.printf(dht11Info.humidity.c_str());

  // Display low to high Temp  
  display.setCursor(40, 1);
  display.printf(day.low.c_str());
  display.setCursor(64, 1);
  display.printf("-");
  display.setCursor(76, 1);
  display.printf(day.high.c_str());
  display.setCursor(100, 1);
  display.printf(" C");

  //Display weather Chinese
  switch(day.code_day)
  {
      case 0:
      case 1: display.drawBitmap(1,3,tianqi[0],16,16,1); // 晴
      break;
      case 4:
      case 5:
      case 6:
      case 7:
      case 8: display.drawBitmap(1,3,tianqi[2],16,16,1); // 多云
              display.drawBitmap(17,3,tianqi[3],16,16,1);
      break;
      case 9: display.drawBitmap(1,3,tianqi[1],16,16,1); // 阴
      break;
      case 10:
      case 11:
      case 12: display.drawBitmap(1,3,tianqi[8],16,16,1); // 阵雨
               display.drawBitmap(17,3,tianqi[9],16,16,1);
      break;
      case 13: display.drawBitmap(1,3,tianqi[4],16,16,1); // 小雨
               display.drawBitmap(17,3,tianqi[9],16,16,1);
      break;
      case 14: display.drawBitmap(1,3,tianqi[5],16,16,1); // 中雨
               display.drawBitmap(17,3,tianqi[9],16,16,1);
      break;
      case 15: display.drawBitmap(1,3,tianqi[6],16,16,1); // 大雨
               display.drawBitmap(17,3,tianqi[9],16,16,1);
      break;
      case 16:
      case 17:
      case 18: display.drawBitmap(1,3,tianqi[7],16,16,1); // 暴雨
               display.drawBitmap(17,3,tianqi[9],16,16,1);
      break;
  }
  display.display();
  delay(2500);
}

void dht11(){
  dht.begin();
  dht11Info.temperature = ftos(dht.readTemperature());
  dht11Info.humidity = ftos(dht.readHumidity());
  delay(300); //wait for reading
}

// convert float to string
String ftos(float val) {
    char buf[200];
    sprintf(buf, "%.1f", val);
    return String(buf);
}

// Web Server GET callback
void handleRoot() {
  if(WiFi.status() != WL_CONNECTED){
        webServer.send(200, "text/html", wifi_html);
    }else{
        webServer.send(200, "text/html", alarm_html);
    }
}

// Web Server POST callback
void handleRootPost() {
    if(WiFi.status() != WL_CONNECTED){
        // parameters exists?
        if (webServer.hasArg("ssid")) {
          Serial.print("got ssid:");
          strcpy(sta_ssid, webServer.arg("ssid").c_str());
          Serial.println(sta_ssid);
        } else {
          Serial.println("error, not found ssid");
          webServer.send(200, "text/html", "<meta charset='UTF-8'>error, not found ssid");
          return;
        }
        if (webServer.hasArg("password")) {
          Serial.print("got password:");
          strcpy(sta_password, webServer.arg("password").c_str());
          Serial.println(sta_password);
        } else {
          Serial.println("error, not found password");
          webServer.send(200, "text/html", "<meta charset='UTF-8'>error, not found password");
          return;
        }
      
        webServer.send(200, "text/html", "<meta charset='UTF-8'>保存成功");
        delay(2000);
        connectNewWifi();
    }else{
        // parameters exists?
        if (webServer.hasArg("asetAlarm")) {
          Serial.print("got asetAlarm:");
          // strcpy(alarm.setAlarm, webServer.arg("asetAlarm").c_str());
          alarm.setAlarm = webServer.arg("asetAlarm");
          Serial.println(alarm.setAlarm);
        } else {
          Serial.println("error, not found asetAlarm");
          webServer.send(200, "text/html", "<meta charset='UTF-8'>请填写完整");
          return;
        }
        if (webServer.hasArg("aHour")) {
          Serial.print("got aHour:");
          // strcpy(alarm.hour, webServer.arg("aHour").c_str());
          alarm.hour = webServer.arg("aHour");
          Serial.println(alarm.hour);
        } else {
          Serial.println("error, not found aHour");
          webServer.send(200, "text/html", "<meta charset='UTF-8'>请填写完整");
          return;
        }
        if (webServer.hasArg("aMinute")) {
          Serial.print("got aMinute:");
          // strcpy(alarm.minute, webServer.arg("aMinute").c_str());
          alarm.minute = webServer.arg("aMinute");
          Serial.println(alarm.minute);
        } else {
          Serial.println("error, not found aMinute");
          webServer.send(200, "text/html", "<meta charset='UTF-8'>请填写完整");
          return;
        }
        webServer.send(200, "text/html", "<meta charset='UTF-8'>保存成功");
    }
}

void connectNewWifi(void){
  WiFi.mode(WIFI_AP_STA);
  WiFi.setAutoConnect(true);
  WiFi.begin(sta_ssid, sta_password);
  Serial.print("\nConnect to wifi");

  display.clearDisplay();
  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.setCursor(0, 24);
  display.printf("Connecting...");
  display.display();
  delay(100);
  
  int count = 0;
   while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    count++;
    // Not connected within 5sec to start web wifi config
    if(count > 20){
      initSoftAP();
      initWebServer();
      initDNS();
      webconfigFlag = true;
      break;
    }
    Serial.print(".");
  }
  Serial.println("");
  if(WiFi.status() == WL_CONNECTED){
    Serial.println("WIFI Connected!");
    Serial.print("IP address: ");
    Serial.println(WiFi.localIP());
    webconfigFlag = false;
    // webServer.stop();
    httpRequest(reqRes); // Update weather info after connected
  }
}

// Initialize AP
void initSoftAP(void){
  WiFi.mode(WIFI_AP_STA);
  WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0));
  if(WiFi.softAP(AP_NAME)){
    Serial.println("ESP8266 AP is ready");
  }
}

// Initialize web server 
void initWebServer(void){
  webServer.on("/", HTTP_GET, handleRoot);
  webServer.onNotFound(handleRoot);
  webServer.on("/", HTTP_POST, handleRootPost);
  webServer.begin();
  Serial.println("WebServer started!");
}

void initDNS(void){
  if(dnsServer.start(DNS_PORT, "*", apIP)){
    Serial.println("dnsserver succeed.");
  }
  else Serial.println("dnsserver failed.");
}

void displayDISCON(int i){
  display.clearDisplay();
  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.setCursor(26, 24);
  display.printf("DISCON!");
  display.display();
  delay(i);
}

void buzzer(){
  int i = 500;
  while(i){
    tone(BUZZER_PIN, 1000);
    delay(i);
    noTone(BUZZER_PIN);
    delay(i=(i-50));
  }
}

//check the set alarm
void checkAlarm(char* Time){
  if (alarm.setAlarm == "1"){
    char now[6] = "";
    strncpy(now,Time,5);
    if(alarm.hour == substring(now,0,2)){
      if(alarm.minute == substring(now,3,2)){
        if(alarm.ringed == false){}
            buzzer();
            alarm.ringed = true;
        }
      }
    }
}

// get sub string
char* substring(char* ch,int pos,int length)  
{  
    char* pch=ch;  
    char* subch=(char*)calloc(sizeof(char),length+1);  
    int i;  
    pch=pch+pos;  
    for(i=0;i<length;i++)  
    {  
        subch[i]=*(pch++);  
    }  
    subch[length]='\0'; 
    return subch;
}
